/* Actual device setup for DMA, etc., if your board * does NOT have hardware scatter/gather DMA support. * Called from the gbdwrite() routine via physio(). */ void gbd_strategy(struct buf *bp) { int unit = geteminor(bp->b_dev)&1; /* any checking for initial state here. */ /* Get the kernel virtual address of the data; note * b_dmaaddr may be NULL if the BP_ISMAPPED(bp) macro * indicates false; in that case, the field bp->b_pages * is a pointer to a linked list of pfdat structure * pointers; that saves creating a virtual mapping and * then decoding that mapping back to physical addresses. * BP_ISMAPPED will never be false for character devices, * only block devices. */ if(!BP_ISMAPPED(bp)) { cmn_err(CE_WARN, "gbd driver can't handle unmapped buffers"); bioerror(bp, EIO); biodone(bp); return; } gbd_curbp[unit] = bp; /* * Initialize the current transfer address and count. * The first transfer should finish the rest of the * page, but do no more than the total byte count. */ gbd_curaddr[unit] = bp->b_dmaaddr; gbd_totcount[unit] = bp->b_count; gbd_curcount[unit] = NBPC - ((unsigned int)gbd_curaddr[unit] & (NBPC-1)); if (bp->b_count < gbd_curcount[unit]) gbd_curcount[unit] = bp->b_count; /* Tell the device starting physical address, count, * and direction */ gbd_device[unit]->startaddr = kvtophys(gbd_curaddr[unit]); gbd_device[unit]->count = gbd_curcount[unit]; if (bp->b_flags & B_READ) == 0) gbd_device[unit]->direction = GBD_WRITE; else gbd_device[unit]->direction = GBD_READ; gbd_device[unit]->command = GBD_GO; /* start DMA */ /* and return; upper layers of kernel wait for iodone(bp) */ }